using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace AppliedRecognition.Speech.TaskSupport
{
	/// <summary>
	/// EnumWindows wrapper for .NET
	/// </summary>
	/// <remarks>
	/// Not for public use
	/// </remarks>
	public abstract class EnumWindows
	{

		internal EnumWindows() {}

    	
		private List<WindowItem> items = null;

		/// <summary>
		/// Returns the collection of windows returned by
		/// GetWindows
		/// </summary>
		/// 
        public List<WindowItem> Items
		{
			get
			{
				return this.items;
			}
		}

		public WindowItem this[int index ]
		{
			get {return items[index]; }
			set { items[index] = value;}

		}


		/// <summary>
		/// Gets all top level windows on the system.
		/// </summary>
		public void GetWindows()
		{
			this.items = new List<WindowItem>();
			PWin32.EnumDesktopWindows(IntPtr.Zero, new PWin32.EnumWindowsProc (this.WindowEnum),IntPtr.Zero);
		}
		/// <summary>
		/// Gets all child windows of the specified window
		/// </summary>
		/// <param name="hWndParent">Window Handle to get children for</param>
		public void GetWindows(IntPtr hWndParent)
		{
			this.items = new List<WindowItem>();
			int ret = PWin32.EnumChildWindows(hWndParent,new PWin32.EnumWindowsProc(this.WindowEnum),0);
			if (ret ==0) throw new System.ComponentModel.Win32Exception(); 
		}

		private IntPtr _shellW;
		public IntPtr ShellWindow 
		{
			get 
			{ 
				if (_shellW == IntPtr.Zero)
				{
					_shellW = PWin32.GetShellWindow(); 
				}
				return _shellW;
			}
		}
		

		protected IntPtr GetOwnerWindow(IntPtr hwnd) {
			IntPtr _ownerHandle = IntPtr.Zero ;
			IntPtr oh = hwnd ;
			do {
				_ownerHandle = oh;
				oh = PWin32.GetWindow(oh,(uint)GW.OWNER);
			}while (oh != IntPtr.Zero && oh !=ShellWindow );
			return _ownerHandle;
		}


		#region EnumWindows callback
		/// <summary>
		/// The enum Windows callback.
		/// </summary>
		/// <param name="hWnd">Window Handle</param>
		/// <param name="lParam">Application defined value</param>
		/// <returns>1 to continue enumeration, 0 to stop</returns>
		private int WindowEnum(IntPtr hWnd,int lParam)
		{
			if (this.OnWindowEnum(hWnd))
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
		#endregion

		/// <summary>
		/// Called whenever a new window is about to be added
		/// by the Window enumeration called from GetWindows.
		/// If overriding this function, return true to continue
		/// enumeration or false to stop.  If you do not call
		/// the base implementation the Items collection will
		/// be empty.
		/// </summary>
		/// <param name="hWnd">Window handle to add</param>
		/// <returns>True to continue enumeration, False to stop</returns>
		protected abstract bool OnWindowEnum(IntPtr hWnd);

		public List<SerialiedWindowItem> GetSerialiedList(bool capScreen) {
            List<SerialiedWindowItem> swil = new List<SerialiedWindowItem>(this.Items.Count);
			foreach (WindowItem wi in this.Items) {
				SerialiedWindowItem swi = new SerialiedWindowItem(wi,capScreen);
				swil.Add(swi);
			}
			return swil;

		}
	
		}   


}